﻿using System;
using System.Collections.Generic;
using Transfer.DataLayer;
using Transfer.DataLayer.LAO;

namespace Transfer
{
    /// <summary> Класс реализует всю бизнес-логику формирования документов ИС-ПРО
    /// на основании входных данных из файла.
    /// </summary>
    public class Processing
    {
        private static ProgressIndicator ProgressInd; // Указатель на метод отображения процента
        
        /// <summary> Метод реализует алгоритм формирования. 
        /// Из входного файла последовательно запрашиваем документы, пока не достигнем конца.
        /// Для каждого документа вызывается соответствующий метод обработки, в зависимости от типа документа.
        /// </summary>
        public static void Go(MainForm frm, ProgressIndicator pi)
        {
            ProgressInd = pi;                           
            
            ActivityLog alog = new ActivityLog();   // Создадим механизм логирования
            alog.outPutLog = frm.SetText;           // Назначим функцию вывода сообщений
            LaoDataSet laoDS = new LaoDataSet();    // Откроем все необходимые объекты LAO

            #region ["Проверим правильность задания налоговой модели и определим ее параметры"]
            try
            {
                laoDS.TaxPrm = new LaoTax(Properties.Settings.Default.TaxModel);
                alog.Out_Log(laoDS.TaxPrm.ToString());
                // Если в настройках налоговой модели НДС не указан - берем его из
                // настроек по умолчанию.
                if (laoDS.TaxPrm.TaxRateValue == 0 && laoDS.TaxPrm.TaxClcMode != TaxCalcMode.Absent)
                    laoDS.TaxPrm.TaxRateValue = Properties.Settings.Default.TaxValue;

                if (laoDS.TaxPrm.TaxModelRcd == 0 /*|| laoDS.TaxPrm.TaxRcd == 0*/)
                {
                    alog.Out_Log("Проверьте настройку налоговой модели.");
                    return;
                }
            }
            catch (Exception ex)
            {
                alog.Out_Log("Ошибка чтения параметров налоговой модели\r\n" + ex.Message);
                return;
            }
            #endregion

            #region ["Настроим прейскуранты и проверим правильность задания шифров"]
            int DefaultPriceRcd = 0;                      // Код прейскуранта реализации
            List <int> DefBuyPriceRcd = new List<int>();    // Коды прейскурантов закупки
            
            try
            {
                // Проверим прайс по умолчанию для реализации
                DefaultPriceRcd = laoDS.Price.GetRcdByCode(Properties.Settings.Default.PriceCode);
                if (DefaultPriceRcd == 0)
                {
                    alog.outPutLog("Проверьте правильность указания шифра прейскуранта реализации.");
                    return;
                }

                // Проверим прайсы для закупки. Их шифры перечислены через пробелы в одном поле.
                string[] prcList = Properties.Settings.Default.BuyPriceCode.Split(' ');
                foreach (string cd in prcList)
                {
                    if (cd.Trim() != String.Empty)
                    {
                        int rcd = laoDS.Price.GetRcdByCode(cd.Trim());
                        if (rcd != 0)
                            DefBuyPriceRcd.Add(rcd);
                    }
                }
                if (DefBuyPriceRcd.Count == 0)
                {
                    alog.outPutLog("Проверьте правильность указания шифров прейскурантов закупки.");
                    return;
                }
            }
            catch (Exception ex)
            {
                alog.outPutLog("Ошибка чтения прейскурантов\r\n" + ex.Message);
                return;
            }
            #endregion

            if (laoDS.KAG.GetRcdByCode(Properties.Settings.Default.CodePost) == 0)
            {
                alog.outPutLog("Ошибка указания кода поставщика для возвратов поставщику.");
                return;
            }

            //------------------- Подготовка закончена, начинаем обработку -----------------------
            Validators valDoc = new Validators();   // Создадим механизм валидации
            valDoc.ALog = alog;                     // Подключим логирование к валидатору
            valDoc.laoDS = laoDS;                   // Укажем валидатору открытые объекты LAO

            // Чтобы выбрать нужный формат, достаточно раскомментировать нужную строку
            //DbfReader dbr = new DbfReader();        // Подключимся к DBF
            CsvReader dbr = new CsvReader();        // Подключимся к CSV
                       
            dbr.SourceFileName = Properties.Settings.Default.InputFileName;
            dbr.Validator = valDoc.DocValidate;     // Подключим метод валидации входных данных
            try
            {
                dbr.LoadData();                         // Грузим данные в DataTable
            }
            catch (Exception ex)
            {
                alog.Out_Log("!!! Ошибка загрузки входных данных \n\r {0}", ex.Message);
                return;
            }
            alog.Out_Log("Из входного файла прочитано документов: {0}", dbr.Count);

            #region ["Запись документов в ИС-ПРО"]
            alog.Out_Log("Запись документов в ИС-ПРО");
            ProgressInd(0);
            LaoTradeDoc laoTrdDoc = new LaoTradeDoc(DefaultPriceRcd, DefBuyPriceRcd); 
            laoTrdDoc.laoDS = laoDS;

            int cnt = 0;
            foreach (InputDocDS.DocHeaderRow row in dbr)        // Перебор документов
            {
                // Здесь мы получаем только те входные документы, которые прошли валидацию.
                // Нужно писать соответствующие им пары документов в ИС-ПРО.
                try
                {
                    if (row.type_doc == "РсНак")
                    {
                        laoTrdDoc.AddDoc(row, CdDoc.IncomBill);    // Запись приходной накладной в ИС-ПРО
                        laoTrdDoc.AddDoc(row, CdDoc.OutcomBill);   // Запись расходной накладной в ИС-ПРО
                    }
                    if (row.type_doc == "ВзПкп")
                    {
                        laoTrdDoc.AddDoc(row, CdDoc.ReversOutcomBill);  // Запись возврата от покупателя в ИС-ПРО
                        laoTrdDoc.AddDoc(row, CdDoc.ReversIncomBill);   // Запись возврата поставщику в ИС-ПРО
                    }
                    cnt++;                                          // Перебор детальных строк документа
                    alog.Out_Log("Сформированы документы ИС-ПРО из входного документа № " + row.num_doc);
                }
                catch (Exception ex)
                {
                    alog.Out_Log("!!! Ошибка формирования документов ИС-ПРО из входного документа {0} № {1} \r\n {2}", row.type_doc, row.num_doc, ex.Message);
                }

                ProgressInd(cnt * 100 / dbr.Count);
            }
            alog.Out_Log("Формирование документов в ИС-ПРО завершено {0}", DateTime.Now);
            #endregion
            alog.Out_Log("Обработано входных документов: " + cnt.ToString());

            laoDS.Close();     // Закрываем LAO-объекты.
        }
    }
}
